#ifndef _HPCR_LIST_H_
#define _HPCR_LIST_H_
#include "hpcr_types.h"
// list node
struct hpcr_list_node
{
    struct hpcr_list_node *pre;
    struct hpcr_list_node *next;
};
typedef struct hpcr_list_node hpcr_list_node_t;

// list
struct hpcr_list
{
    hpcr_list_node_t head;
    hpcr_list_node_t tail;
};
typedef struct hpcr_list hpcr_list_t;

#define list_element(x, y) ((y *)x)

typedef bool hpcr_list_node_compare_handle(hpcr_list_node_t *, hpcr_list_node_t *);
typedef bool hpcr_list_node_search_handle(hpcr_list_node_t *, void *arg);

hpcr_list_t *hpcr_list_init(hpcr_list_t *list);
void hpcr_list_push(hpcr_list_t *list, hpcr_list_node_t *node);
void hpcr_list_append(hpcr_list_t *list, hpcr_list_node_t *node);
bool hpcr_list_remove(hpcr_list_node_t *node);
hpcr_list_node_t *hpcr_list_pop(hpcr_list_t *list);
void hpcr_list_insert_order(hpcr_list_t *list, hpcr_list_node_t *node, hpcr_list_node_compare_handle compare);

hpcr_list_node_t *hpcr_list_find(hpcr_list_t *list, hpcr_list_node_search_handle, void *arg);
bool hpcr_list_empty(hpcr_list_t *list);
hpcr_size_t hpcr_list_size(hpcr_list_t *empty);

void hpcr_list_insert_before(hpcr_list_node_t *dst, hpcr_list_node_t *node);
void hpcr_list_insert_after(hpcr_list_node_t *dst, hpcr_list_node_t *node);
#endif
